/**
 * @file        freertos.c
 * @author      正点原子团队(ALIENTEK)
 * @version     V1.4
 * @date        2022-01-04
 * @brief       FreeRTOS 移植实验
 * @license     Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
 */

#include "userConfig.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   256
TaskHandle_t    start_task_handler;

/* TASK1 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   256
TaskHandle_t    task1_handler;


/* TASK2 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   256
TaskHandle_t    task2_handler;

/* TASK3 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK3_PRIO         4
#define TASK3_STACK_SIZE   256
TaskHandle_t    task3_handler;


QueueHandle_t key_queue;        /* 小数据句柄 */
QueueHandle_t big_date_queue;   /* 大数据句柄 */

char buff[100] = {"我是一个大数组，大大的数组 124214 uhsidhaksjhdklsadhsaklj"};




/* 任务一，实现入队 */
static void task1(void *pvParameters)
{
    uint8_t key = 0;
    char * buf;
    BaseType_t   err = 0;
    buf = &buff[0]; /* buf = &buff[0] */
    while(1)
    {
        if(key == 0)
        {
            err = xQueueSend(key_queue, &key, portMAX_DELAY);
            if(err != pdTRUE)
            {
                usart_transmit("key_queue队列发送失败\r\n");
            }
            key = 1;
        } else if(key == 1)
        {
            key = 0;
            err = xQueueSend(big_date_queue, &buf, portMAX_DELAY);
            if(err != pdTRUE)
            {
                usart_transmit("key_queue队列发送失败\r\n");
            }
        }
        vTaskDelay(100);
    }
}

/* 任务二，小数据出队 */
static void task2(void *pvParameters)
{
    uint8_t key = 0;
    BaseType_t err = 0;
    while(1)
    {
        err = xQueueReceive(key_queue, &key, portMAX_DELAY);
        if(err != pdTRUE)
        {
            usart_transmit("key_queue队列读取失败\r\n");
        }else
        {
            usart_transmit("key_queue读取队列成功, 数据: %d\r\n",key);
        }
    }
}

/* 任务三，大数据出队 */
static void task3(void *pvParameters)
{
    char * buf;
    BaseType_t err = 0;
    while(1)
    {
        err = xQueueReceive(big_date_queue, &buf, portMAX_DELAY);
        if(err != pdTRUE)
        {
            usart_transmit("big_date_queue队列读取失败\r\n");
        }else
        {
            usart_transmit("数据：%s\r\n",buf);
        }
    }
}

static void start_task(void * pvParameters)
{
    taskENTER_CRITICAL();
    xTaskCreate((TaskFunction_t         )   task1,
                (char *                 )   "task1",
                (configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK1_PRIO,
                (TaskHandle_t *         )   &task1_handler);

    xTaskCreate((TaskFunction_t         )   task2,
                (char *                 )   "task2",
                (configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK2_PRIO,
                (TaskHandle_t *         )   &task2_handler);

    xTaskCreate((TaskFunction_t         )   task3,
                (char *                 )   "task3",
                (configSTACK_DEPTH_TYPE )   TASK3_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK3_PRIO,
                (TaskHandle_t *         )   &task3_handler);

    vTaskDelete(NULL);
    taskEXIT_CRITICAL();
}

void queue_demo(void)
{
    /* 队列的创建 */
    key_queue = xQueueCreate(2, sizeof(uint8_t));
    if(key_queue != NULL)
    {
        usart_transmit("key_queue队列创建成功\r\n");
    }
    else
    {
        usart_transmit("key_queue队列创建失败\r\n");
    }

    big_date_queue = xQueueCreate(1, sizeof(char *));
    if(big_date_queue != NULL)
    {
        usart_transmit("big_date_queue队列创建成功\r\n");
    }
    else
    {
        usart_transmit("big_date_queue队列创建失败\r\n");
    }

    xTaskCreate((TaskFunction_t         )   start_task,
                (char *                 )   "start_task",
                (configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   START_TASK_PRIO,
                (TaskHandle_t *         )   &start_task_handler);
}
